package com.qfedu.fmmall.service.impl;


import com.qfedu.fmmall.dao.*;
import com.qfedu.fmmall.entity.*;
import com.qfedu.fmmall.service.OrderService;
import com.qfedu.fmmall.utils.PageHelper;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVo;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ProductSkuMapper productSkuMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Transactional
    public Map<String,String> addOrder(String cids, Orders orders) {
        Map<String,String> map = new HashMap<>();

        //1.校验库存：根据cid查询当前订单中关联的购物车记录详情（包括库存）
        String[] arr = cids.split(",");
        List<Integer> cidsList = new ArrayList<>();
        for (int i = 0; i < arr.length; i++) {
            cidsList.add(Integer.parseInt(arr[i]));//把cid换城int类型，并保存进cidsList中
        }
        //查询购物车数据
        List<ShoppingCartVo> list = shoppingCartMapper.selectShopCartByCIds(cidsList);

        //分布式锁，防止商品超卖
        Boolean isLock = true;
        String[] skuIds = new String[list.size()];
        Map<String, RLock> lockMap = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {
            String skuId = list.get(i).getSkuId();
            RLock lock = redissonClient.getLock(skuId);
            Boolean ifAbsent = false;
            try {
                ifAbsent = lock.tryLock(10, 3, TimeUnit.SECONDS);
                if(ifAbsent){
                    skuIds[i] = skuId;
                    lockMap.put(skuId,lock);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            isLock = isLock && ifAbsent;

        }
        try{
            if(isLock){

                //检测库存
                boolean f = true;
                String untitled = "";
                for (ShoppingCartVo vo: list) {
                    if(Integer.parseInt(vo.getCartNum())>vo.getSkuStock()){ //购买数量减去总库存，大于了就返回false 购买不了
                        f=false;
                    }
                    //获取所有商品名称，以，分割拼接成字符串
                    untitled = untitled+vo.getProductName()+",";
                }
                if(f){
                    //2.保存订单
                    orders.setUntitled(untitled);
                    orders.setCreateTime(new Date());
                    orders.setStatus("1");
                    //生成订单编号
                    String orderId = UUID.randomUUID().toString().replace("-","");
                    orders.setOrderId(orderId);
                    //保存
                    ordersMapper.insert(orders);

                    //3.生成商品快照
                    list = shoppingCartMapper.selectShopCartByCIds(cidsList);
                    for (ShoppingCartVo sc:list) {
                        int cnum = Integer.parseInt(sc.getCartNum());
                        String itemId = System.currentTimeMillis()+""+(new Random().nextInt(89999)+10000);
                        OrderItem orderItem = new OrderItem(itemId,orderId,sc.getProductId(),sc.getProductName(),
                                sc.getProductImg(),sc.getSkuId(),sc.getSkuName(),new BigDecimal(sc.getSellPrice())
                                ,cnum,new BigDecimal(sc.getOriginalPrice()*cnum),new Date(),new Date(),0);
                        orderItemMapper.insert(orderItem);
                    }
                    //4.扣减库存，根据套餐ID修改套餐库存量
                    for(ShoppingCartVo sc:list){
                        String skuId = sc.getSkuId();
                        int newStock = sc.getSkuStock()-Integer.parseInt(sc.getCartNum());//减去购买的库存，把剩余库存保存

                        ProductSku sku = new ProductSku();
                        sku.setSkuId(skuId);
                        sku.setStock(newStock);
                        productSkuMapper.updateByPrimaryKeySelective(sku);

                    }
                    //5.删除购物车：当购物车中记录购买成功之后，购物车中对应做删除操作
                    for (int cid:cidsList) {
                        shoppingCartMapper.deleteByPrimaryKey(cid);
                    }
                    //return new ResultVo(ResultStatus.OK,"下单成功",orderId);
                    map.put("orderId",orderId);
                    map.put("productNames",untitled);

                }



            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            //释放锁
            for (int i = 0; i < skuIds.length; i++) {
                String skuId = skuIds[i];
                if(skuId != null || "".equals(skuIds[i])){
                    lockMap.get(skuId).unlock();
                }
            }
        }




        return  map;
    }

    @Override
    public int updateOrderStatus(String orderId, String status) {

        Orders orders = new Orders();
        orders.setOrderId(orderId);
        orders.setStatus(status);

        int i = ordersMapper.updateByPrimaryKey(orders);
        return i;
    }

    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE) //线程锁，排队执行，防止同时执行出错
    public void closeOrder(String orderId) {
       synchronized (this){
           //1.先去将订单状态修改为6，取消状态为1
           Example example = new Example(Orders.class);
           Example.Criteria criteria = example.createCriteria();
           Orders orders = new Orders();
           orders.setOrderId(orderId);
           orders.setStatus("6");
           orders.setCloseType(1);
           ordersMapper.updateByPrimaryKey(orders);

           //2.恢复商品库存(先查找出订单快照)
           Example example1 = new Example(OrderItem.class);
           Example.Criteria criteria1 = example1.createCriteria();
           criteria1.andEqualTo("orederId",orderId);
           List<OrderItem> orderItems = orderItemMapper.selectByExample(example1);
           //遍历把库存恢复
           for (int i = 0; i < orderItems.size(); i++) {
               OrderItem orderItem = orderItems.get(i);
               ProductSku productSku = productSkuMapper.selectByPrimaryKey(orderItem.getSkuId());
               productSku.setStock(productSku.getStock()+orderItem.getBuyCounts());
               productSkuMapper.updateByPrimaryKey(productSku);

           }


       }


    }

    @Override
    public ResultVo OrderList(String userId, String status, int pageNum, int limit) {
        //获取当前页的起始值
        int start = (pageNum-1)*limit;
        List<OrdersVo> ordersVos = ordersMapper.selectOrders(userId, status, start, limit);
        System.out.println("-------------");
        System.out.println(ordersVos);
        //获取数据总数
        Example example = new Example(Orders.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        if(status!=null || "".equalsIgnoreCase(status)){
            criteria.andEqualTo("status",status);
        }
        int count = ordersMapper.selectCountByExample(example);

        //获取总页数
        int pageCount = count % limit == 0 ?count/limit : count/limit+1;

        PageHelper<OrdersVo> PageHelper = new PageHelper<>(count, pageCount, ordersVos);


        return new ResultVo(ResultStatus.OK,"success",PageHelper);
    }
}
